#include "common.h"
int flag = 1;

int main()
{ 
	//定义变量
	int socketID = 0;
	
	//初始化socket : 创建socket，bind， listen
	socketID = socketInit(IP, SPORT, 10);
	
	//初始化select相关参数
	int maxFd = socketID;
	fd_set readFds;
	fd_set tmpFds;
	FD_ZERO(&readFds);
	FD_SET(socketID, &readFds);
	tmpFds = readFds;
	
	while (1)
	{
		//将tmpFds赋值给readFds
		readFds = tmpFds;
		struct timeval tv = {
			.tv_sec = 15,
		};
		//调用select
		int ret = select(maxFd + 1, &readFds, NULL, NULL, &tv);
		//判断返回值
		if (0 > ret)
		{
			perror("select error");
			break;
		}
		else if ( 0 == ret )
		{
			printf("select time out\r\n");
			continue;
		}
		//遍历select返回的readFds，进行相应的IO操作
		int i = 0;
		for (i = 0; i <= maxFd; i++)
		{
			if (FD_ISSET(i, &readFds))
			{
				if ( socketID == i )
				{
					getLink(i, &tmpFds, &maxFd);
				}
				else 
				{
					doClientProcess(i, &tmpFds);
				}
			}
		}
	}
	//关闭socket
	close(socketID);
	return 0;
}
/*处理客户端的消息，如果客户端断开连接，需要更新tmpFds*/
int doClientProcess(int newID, fd_set * tmpFds )
{
	printf("处理客户端的消息，如果客户端断开连接，需要更新tmpFd\r\n");
	//接收客户端的命令+文件名
	S_MSG msg;
	while(1)
	{
		int ret = recv(newID, &msg, sizeof(msg), 0);// MSG_WAITALL
		if ( 0 > ret )
		{
			perror("recv error");
			close(newID);
			FD_CLR(newID, tmpFds);
			return -1;
		}
		else if ( 0 == ret )
		{
			printf("客户端%d已经断开连接\r\n", newID);
			close(newID);
			FD_CLR(newID, tmpFds);
			return -1;
		}
		printf("=====================\r\n");
		printf("%c\r\n",msg.cmd);
		if('o' == msg.cmd)
		{
			printf("&&&&&&&&\r\n");
			break;
		}
		int fd;
		char c;
		
		fd = open("/dev/ttyUSB0",O_RDWR);//打开设备节点
		if(fd < 0)
		{
			printf("open failed\n");
			return -1;
		}
		//printf("open ok\r\n");
		
		init_tty(fd);
		int pid = fork();
		if(-1 == pid)
		{
			perror("fork error");
			return -1;
		}
		else if(0 == pid)
		{
			doRead(fd, newID, tmpFds);
		}
		dofeng_on(msg.cmd, fd);
	}
	//关闭已经连接的socket
	close(newID);			
	//需要更新tmpFds
	FD_CLR(newID, tmpFds);
	return 0;
}

int doRead(int fd, int newID, fd_set * tmpFds)
{
	int ret = 0;
	char buf[100] = {0};
	while(1)
	{
		sleep(3);
		ret = read(fd, buf, 100);
		if(ret < 0)
		{
			printf("read error\n");
		}
		//printf("ret is %d\n", ret);
		
		int ret = send(newID, buf, sizeof(buf), 0);
		//printf("recv data is %s\n", buf);
		if ( 0 > ret )
		{
			perror("send error");
			close(newID);
			FD_CLR(newID, tmpFds);
			return -1;
		}
	}
	close(fd);
	return 0;
}

int dofeng_on(char cmd, int fd)
{	
	write(fd, &cmd, 1);
	//printf("write ok\r\n");
	
	close(fd);
	return 0;
}


/*接受客户端的连接，更新tmpFds，更新maxFd*/
int getLink(int socketID, fd_set * tmpFds, int * maxFd)
{
	int addrLength = 0;
	struct sockaddr_in addr;
	int newID = 0;
	
	addrLength = sizeof(addr);
	newID = accept(socketID, (struct sockaddr *)&addr, &addrLength);
	if ( 0 > newID )
	{
		perror("accept error");
		return -1;
	}
	printf("server is connected by ip: %s,", inet_ntoa(addr.sin_addr));
	printf("port: %u,", ntohs(addr.sin_port));
	printf("newID=%d\r\n", newID);
	
	//更新tmpFds，
	FD_SET(newID, tmpFds);
	
	//更新maxFd 
	if ( * maxFd < newID )
	{
		* maxFd = newID;
	}
	
	return 0;
}


/*初始化socket  创建socket, bind, listen*/
int socketInit(const char * ip, unsigned short port, int listenNum)
{
	int socketID = 0;
	//创建socket
	socketID = socket( PF_INET, SOCK_STREAM, 0);
	if ( 0 > socketID )
	{
		perror("socket error");
		exit(0);
	}
	printf("socket ok\r\n");
	
	//设置地址复用
	int on = 1;
	if (0 > setsockopt( socketID, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) )
	{
		perror("setsockopt error");
	}
	
	//绑定
	struct sockaddr_in addr = {
		.sin_family = PF_INET,
		.sin_port   = htons(port),
		.sin_addr   = {
			.s_addr = INADDR_ANY,
		},
	};
	if ( 0 > bind( socketID, (struct sockaddr *)&addr, sizeof(addr) ) )
	{
		perror("bind error");
		goto ERROR;
	}
	printf("server bind ok\r\n");
	//监听
	if ( 0 > listen( socketID, listenNum ) )
	{
		perror("listen error");
		goto ERROR;
	}
	printf("server listen ok\r\n");
	//返回
	return socketID;
ERROR:
	close(socketID);
	exit(0);
}

void init_tty(int fd)
{
	struct termios newtio;
	struct termios oldtio;
	bzero(&newtio,sizeof(struct termios));//全部初始化为零
	tcgetattr(fd,&oldtio);//获得 原有的数据保存到oldtio里
	newtio.c_cflag |= CLOCAL | CREAD;//接受使能  
	cfsetispeed(&newtio,B115200);//设置输入速度
	cfsetospeed(&newtio,B115200);// 设置输出速度
	//printf("c_cflag=%x\n",newtio.c_cflag);
	newtio.c_cflag &= ~CSIZE;//对应比特位清零
	//printf("c_cflag=%x\n",newtio.c_cflag);
	newtio.c_cflag |= CS8;
	//printf("c_cflag=%x\n",newtio.c_cflag);
	
	//设置无校验
	newtio.c_cflag &= ~PARENB;
	newtio.c_iflag &= ~INPCK;
	//设置停止位
	newtio.c_cflag &= ~CSTOPB;
	//设置等待时间和接受字符
	newtio.c_cc[VTIME] = 0;
	newtio.c_cc[VMIN] = 0;
	//设置原始模式
	newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	newtio.c_lflag &= ~OPOST;
	//刷新串口缓冲
	tcflush(fd,TCIOFLUSH);
	//设置新的串口属性
	tcsetattr(fd,TCSANOW,&newtio);
}

